﻿using System;
using System.Collections.Generic;
using System.Linq;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.GamePlay;

namespace IQIGame.Onigao.Logic
{
    public static class BuffFactory
    {
        private static BuffEffective[] mEffectiveMap;
        public static BuffHandler CreateBuff(BuffComponent rMaker, BuffComponent rTarget, int nBuffID)
        {
            var rConfig = TableCenter.buff.Get(nBuffID);
            if (rConfig == null)
            {
                return null;
            }
            var rHandler = ClassPool.Get<BuffHandler>();
            rHandler.maker = rMaker;
            rHandler.target = rTarget;
            rHandler.buffID = nBuffID;
            rHandler.config = rConfig;
            rHandler.maxStack = rConfig.MaxNum;
            rHandler.addType = (EBuffAddType)rConfig.AddType;
            rHandler.timeDuration = rConfig.Duration;
            rHandler.triggerType = (EBuffDotTriggerType)rConfig.DotExecute;
            
            var rEffect = rHandler.config.Effect;
            for (int i = 0; i < rEffect.Count; i++)
            {
                rHandler.effectives.Add(CreateEffective(rEffect[i], rTarget));
            }
            // Dot
            if (rConfig.Dot.Count > 0)
            {
                rHandler.dotFormula = rConfig.Dot[0];
                rHandler.dotType = rConfig.DotType;
                if (rHandler.dotType == 0 && rConfig.Dot.Count > 1)
                {
                    rHandler.dotDamageType = (EDamageType)(1 << rConfig.Dot[1]);
                }
            }
            
            return rHandler;
        }

        private static BuffEffectData CreateEffective(int nEffectiveID, BuffComponent rTarget)
        {
            var rData = ClassPool.Get<BuffEffectData>();
            rData.id = nEffectiveID;
            var rTable = TableCenter.buffeffect.Get(nEffectiveID);
            rData.param.AddRange(rTable.EffectParam);
            rData.paramStr.AddRange(rTable.EffectStringParam);
            rData.effective = GetEffective((EBuffEffectiveType)rTable.Type);

            rData.effective.InitProperty(rData, rTarget);
            return rData;
        }
        
        private static BuffEffective GetEffective(EBuffEffectiveType rType)
        {
            if (mEffectiveMap == null || mEffectiveMap.Length == 0)
            {
                mEffectiveMap = new BuffEffective[(int)EBuffEffectiveType.Max];
                mEffectiveMap[(int)EBuffEffectiveType.AttrChange] = new BuffEffective_AttrChange();
                // mEffectiveMap[EBuffEffectiveType.Damage] = new BuffEffective_Damage();
                mEffectiveMap[(int)EBuffEffectiveType.Burnout] = new BuffEffective_Burnout();
                mEffectiveMap[(int)EBuffEffectiveType.Shield] = new BuffEffective_Shield();
                mEffectiveMap[(int)EBuffEffectiveType.AddSkill] = new BuffEffective_AddSkill();
                // mEffectiveMap[EBuffEffectiveType.ReplaceTargetBySkillType] = new BuffEffective_ReplaceTargetBySkillType();
                mEffectiveMap[(int)EBuffEffectiveType.CustomState] = new BuffEffective_CustomState();
                mEffectiveMap[(int)EBuffEffectiveType.ReplaceSkill] = new BuffEffective_ReplaceSkill();
                mEffectiveMap[(int)EBuffEffectiveType.Morph] = new BuffEffective_Morph();
            }
            return mEffectiveMap[(int)rType];
        }
    }
}